﻿using System;
using System.Collections.Generic;
using System.Text;
using FrameworkX.ObjectSpace.Data.SqlObjects;
using FrameworkX.ObjectSpace;
using System.Collections;


namespace FrameworkX.TinyCms.Core.Security
{    
    class SecurityService : FrameworkX.TinyCms.Core.Service.IService
    {
        Database Database;

        public long CreateAccessRight(AccessRight accessRight)
        {
            return Database.Insert(accessRight);
        }

        public bool RemoveAccessRight(long accessRightID)
        {
            int result = Database.Delete(typeof(AccessRight), accessRightID);
            return (result > 0);
        }

        public AccessRight GetAccessRight(long accessRightID)
        {
            return Database.Select<AccessRight>(accessRightID);
        }

        public IList<AccessRight> GetRightsForGroup(long groupID)
        {
            string sql = "SELECT * AccessRight FROM AccessRight WHERE AccessRightID in " +
                "( SELECT AccessRightID FROM GroupAccessRightMap WHERE GroupID = " + groupID + " )";

            IList rights = Database.SelectBySQL(typeof(AccessRight), sql);

            IList<AccessRight> accessRights = new List<AccessRight>();
            foreach (AccessRight right in rights)
            {
                accessRights.Add(right);
            }

            return accessRights;
        }

        public IList<AccessRight> GetRightsForUser(long userID)
        {
            string sql = "SELECT * FROM AccessRight WHERE AccessRightID in " +
                "( SELECT AccessRightID FROM GroupAccessRightMap WHERE GroupID in " +
                "( SELECT GroupID FROM UserGroupMap WHERE UserID = " + userID + " ))";

            IList rights = Database.SelectBySQL(typeof(AccessRight), sql);

            IList<AccessRight> accessRights = new List<AccessRight>();
            foreach (AccessRight right in rights)
            {
                accessRights.Add(right);
            }

            return accessRights;
        }

        public bool UserHasRight(long userID, long rightID)
        {
            string sql = "SELECT * FROM AccessRight WHERE AccessRightID=" + rightID.ToString() +
                " AND AccessRightID in " +
                "( SELECT AccessRightID FROM GroupAccessRightMap WHERE GroupID in " +
                "( SELECT GroupID FROM UserGroupMap WHERE UserID = " + userID + " ))";

            IList rights = Database.SelectBySQL(typeof(AccessRight), sql);
            if (rights.Count > 0)
            {
                return true;
            }
            else
            {
                return false;
            }

        }



        /// <summary>
        /// Creates a user object in database
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public long CreateUser(User user)
        {
            user.UserID = Database.Insert(user);
            return user.UserID;
        }

        public bool Update(User user)
        {
            bool result = false;

            int status = Database.Update(user);

            // check
            if (status > 0)
            {
                result = true;
            }

            return result;
        }

        public int  DeleteUser(long userId)
        {
            return Database.Delete(typeof(User), userId);
        }

        /// <summary>
        /// Gets a user object by ID
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        public User GetUser(long userID)
        {
            return Database.Select<User>(userID);
        }


        /// <summary>
        /// Gets a user object by login
        /// </summary>
        /// <param name="login"></param>
        /// <returns></returns>
        public User GetUser(string login)
        {            
            WhereClause wc = DataAccessHelper.GetUserByLogin(login);
            IList<User> users = Database.SelectBy<User>(wc, null);
            if (users.Count == 1)
            {
                return users[0];
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Returns all users in the system
        /// </summary>
        /// <returns></returns>
        public IList<User> GetUsers()
        {
            return Database.SelectAll<User>();
        }

        internal IList<Group> GetGroups()
        {
            return Database.SelectAll<Group>();
        }

        public Group GetGroup(long groupID)
        {
            return Database.Select<Group>(groupID);
        }

        public long CreateGroup(Group group)
        {
            group.GroupID = Database.Insert(group);
            return group.GroupID;
        }

        public bool Update(Group group)
        {
            bool result = false;

            int status = Database.Update(group);

            if (status > 0)
            {
                result = true;
            }
            return result;
        }

        public int DeleteGroup(long groupId)
        {
            return Database.Delete(typeof(Group), groupId);
        }

        public long InsertUserGroupMap(UserGroupMap map)
        {
            map.UserGroupMapID = Database.Insert(map);
            return map.UserGroupMapID;
        }


        /// <summary>
        /// Checks if user is assigned to group
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="groupID"></param>
        /// <returns></returns>
        public bool IsUserAssignedToGroup(long userID, long groupID)
        {
            WhereClause wc = DataAccessHelper.GetUserGroupMapByUserIDGroupID(userID, groupID);
            IList<UserGroupMap> maps = Database.SelectBy<UserGroupMap>(wc, null);

            if (maps.Count > 0)
                return true;
            else
                return false;
        }

        public IList<UserGroupMap> GetUserGroupMapsByUserID(long userID)
        {
            WhereClause wc = DataAccessHelper.GetUserGroupMapByUserID(userID);
            return Database.SelectBy<UserGroupMap>(wc, null);
        }

        internal IList<UserGroupMap> GetUserGroupMapsByGroupID(long groupID)
        {
            WhereClause wc = DataAccessHelper.GetUserGroupMapByGroupID(groupID);
            return Database.SelectBy<UserGroupMap>(wc, null);
        }



        internal void RemoveAllUsersFromGroup(long groupID)
        {
            WhereClause wc = DataAccessHelper.RemoveAllUsersFromGroup(groupID);
            Database.DeleteBy(typeof(UserGroupMap), wc);
        }




        public bool RemoveAccessRightsForGroup(long groupID)
        {
            WhereClause wc = DataAccessHelper.RemoveAccessRightsByGroup(groupID);
            Database.DeleteBy(typeof(GroupAccessRightMap), wc);
            return true;
        }



        public bool RemoveAccessRightsForGroup(long[] accessRights, long groupID)
        {
            WhereClause wc = DataAccessHelper.RemoveAccessRightsByGroup(accessRights, groupID);
            Database.DeleteBy(typeof(GroupAccessRightMap), wc);
            return true;
        }

        public IList<AccessRight> GetAccessRights()
        {
            return Database.SelectAll<AccessRight>();
        }

        public int InsertGroupAccessRightMap(GroupAccessRightMap map)
        {
            return Database.Insert(map);
        }

        public int DeleteGroupAccessRightMap(long groupAccessRightMapID)
        {
            return Database.Delete(typeof(GroupAccessRightMap), groupAccessRightMapID);
        }

        public IList<GroupAccessRightMap> GetGroupAccessRightMapByGroupID(int groupID)
        {
            WhereClause wc = DataAccessHelper.GetGroupAccessRightMapByGroupID(groupID);
            return Database.SelectBy<GroupAccessRightMap>(wc, null);
        }


        internal bool GroupHasRight(long groupID, long accessRightID)
        {
            WhereClause wc = DataAccessHelper.GetGroupAccessRightMap(groupID, accessRightID);
            IList<GroupAccessRightMap> list = Database.SelectBy<GroupAccessRightMap>(wc, null);
            AccessRight right = Database.Select<AccessRight>(accessRightID);
            if (list.Count > 0)
            {
                return true;
            }
            else
            {
                return right.DefaultValue;
            }
        }

    }
}
